/*******************************************************************************
*   Copyright (C) Harbin Institute of Technology, Shenzhen.
*				  All Rights Reserved.
*   Department: Decoration
********************************************************************************
* File Name   : timer_if.h
* Author      : Dayuan
* Version     : v0.01
* Date        : 2019/9/2
* Description : Decoration Rototics Manipulator task.
*******************************************************************************/
/*-History----------------------------------------------------------------------
* Version   Date      Name        Changes and comments
* v0.01     2019/9/2  Dayuan    initial version
*=============================================================================*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef _TIMER_IF_H_
#define _TIMER_IF_H_

#ifdef __cplusplus
 extern "C" {
#endif
     
/**** Includes ****/
#include <stdint.h>
     
/**** Definition of constants ****/


 
/**** Definition of types ****/ 
struct SYS_TIME 
{
  volatile uint32_t nb_sec;       ///< full seconds since startup
  volatile uint32_t nb_sec_rem;   ///< remainder of seconds since startup in CPU_TICKS
  volatile uint32_t nb_tick;      ///< SYS_TIME_TICKS since startup

  float resolution;               ///< sys_time_timer resolution in seconds
  uint32_t ticks_per_sec;         ///< sys_time ticks per second (SYS_TIME_FREQUENCY)
  uint32_t resolution_cpu_ticks;  ///< sys_time_timer resolution in cpu ticks
  uint32_t cpu_ticks_per_sec;     ///< cpu ticks per second
};

/**** Definition of macros ****/
#define TIMER_TIMEOUT               0x0000
#define TIMER_NOT_ACTIVE            0xFFFF
#define TIMER_NO_PARAM              0x00
#define TIMER_NO_BACKUP_COUNTER     0xFFFF
#define TIMER_MAX_SYS_TIMER_TICK    0xFFFF

/**** Declaration of constants ****/
#define HW_TIMER_TICK                   1	/* 1ms */
#define SYS_TIMER_COUNTER               5
#define SYS_TIMER_TICK                  (SYS_TIMER_COUNTER)   /* SYS_TIMER_COUNTER*HW_TIMER_TICK */

#define MSECOND     / SYS_TIMER_TICK
#define SECOND      *1000L/ SYS_TIMER_TICK
#define MSECONDS    / SYS_TIMER_TICK
#define SECONDS     *1000L/ SYS_TIMER_TICK
#define MINUTE      *60000L/ SYS_TIMER_TICK
#define MINUTES     *60000L/ SYS_TIMER_TICK
/**** Declaration of variables ****/
extern struct SYS_TIME sys_time;

/**** Declaration of functions ****/
extern void sys_timer_isr_handler(void);
extern uint32_t systick_get_value(void);
extern void sys_time_init(void);
extern int32_t max_timer_error(int32_t usec);
extern void delay_us(uint16_t us);
extern uint32_t force_timer_reset(void);

static inline uint32_t sys_time_ticks_of_usec(uint32_t usec)
{
  return usec * sys_time.ticks_per_sec / 1000000;
}

static inline uint32_t usec_of_cpu_ticks(uint32_t cpu_ticks)
{
  return cpu_ticks / (sys_time.cpu_ticks_per_sec / 1000000);
}



/**
 * Get the time in microseconds since startup.
 * WARNING: overflows after 70min!
 * @return microseconds since startup as uint32_t
 */
static inline uint32_t get_sys_time_usec(void)
{
  return sys_time.nb_sec * 1000000 +
         usec_of_cpu_ticks(sys_time.nb_sec_rem) +
         usec_of_cpu_ticks(systick_get_value());
}
#ifdef __cplusplus
}
#endif

#endif
